const path = require('path')

module.exports = (env) => {
  // 使用环境变量
  console.log('Production: ', env.production) // true
  return {
    // 生产环境将默认使用 TerserPlugin 来压缩并且混淆代码
    mode: env.production ? 'production' : 'development',
    entry: {
      nim: './src/index.ts',
      V2NIMTestService: './src/V2NIMTestServiceImpl.ts'
    },
    // 不开启混淆代码, 通常是 mode: production 后. 想要辅助调试而开启的配置.
    // optimization: {
    //   minimize: false
    // },

    // 之前 webpack4 只是粗暴的支持两种：target: 'web', target: 'node'.
    // 现在 webpack5默认是 ['web', 'es6']，也就是说会默认打包出es6产出. 也就是说会默认打包出 es6 产出. 效果就是 webpackBootstrap 注入代码会含有 => 箭头函数.
    // 如果为了让产物支持 IE 低版本, 除了配置 @babel/preset-env 以及 @babel/plugin-transform-runtime 外, 仍然需要配置 target: ['web', 'es5']
    target: ['web', 'es6'],

    // mode 为 development 时使用 inline-source-map 会内联插入代码，可以追踪错误代码准确信息和源代码的错误位置. 显著增加 bundle 体积, 降低整体性能, 但是构建速度快
    // mode 为 production 时应该选用 source-map. 外置一个 sourceMap 文件, 同样可以追踪错误代码准确信息和源代码的错误位置
    // 打开这个选项后, development 产出的 bundle.js 从 555kb 提升到 1.38MB
    // 代码里产生的错误有更明显的指引.
    // ...(env.production ? { devtool: 'source-map' } : { devtool: 'inline-source-map' }),

    output: {
      // library 产物名, 记得需要去 package.json 里加入 main: "dist/webpack-numbers.js" 和 module: "src/index.js"
      filename: '[name].js',
      path: path.resolve(__dirname, 'dist'),
      // 做一个 library 需要从 output.library 配置项暴露从入口导出的内容。
      // 这样使用者可以通过 import NIM from 'webpack-numbers'
      // 并且导出格式是 umd 的, 可以被用在 ES6 的 import 上, commonjs 的 require 上, 还可以是 AMD 和 script 引入
      library: ['[name]'],
      libraryTarget: 'umd',
      // 在每次构建前清理 /dist 文件夹
      clean: true
    },
    // 把 lodash 给视为外部依赖, 注意在 package.json peerDependency 选项里加入 lodash
    externals: {
      '@babel/runtime/regenerator': 'commonjs2 @babel/runtime/regenerator',
      '@babel/runtime/helpers/asyncToGenerator': 'commonjs2 @babel/runtime/helpers/asyncToGenerator',
      '@babel/runtime/helpers/classCallCheck': 'commonjs2 @babel/runtime/helpers/classCallCheck'
      // 添加其他需要的 helpers...
    },
    module: {
      rules: [
        // 配置 ts 解析 loader
        // npm install -D typescript ts-loader  @babel/preset-typescript
        // npm install -D babel-loader @babel/core @babel/preset-env core-js
        // npm install -D @babel/plugin-transform-runtime @babel/runtime-corejs3
        // use 数组的加载器是从右到左执行的。首先，ts-loader 将 TypeScript 代码编译成 JavaScript，然后 babel-loader 对编译后的 JavaScript 代码进行进一步处理。
        {
          test: /\.tsx?$/,
          use: [
            {
              loader: 'babel-loader',
              options: {
                presets: [
                  [
                    // @babel/preset-env 用来转 const, => 等 ES6 语法转化的 (看起来会把 async/await 转为 Iterator 迭代器实现)
                    // 不会补齐 Promise, Map 这种 API 性质的
                    '@babel/preset-env',

                    {
                      // usage 含义为根据 browserslist 的所支持的浏览器去决定该语法是否需要 polyfill (拒绝)
                      // 使用 preset-env 注入的 polyfill 是会污染全局的, 写库的时候不应该开启
                      useBuiltIns: false,
                      targets: {
                        browsers: ['last 2 versions', 'ie >= 9', 'android > 4']
                      }
                      // 如果在 @babel/plugin-transform-runtime 的 corejs3 打开 polyfill 的情况下,
                      // 仍旧打开以下的配置这个会使得产物体积从 55kb 上升到 84kb
                      // 这个 usage 且 corejs3 是 preset-env 提供的注入全局的 polyfill, 写 library 时不应该开启
                      // useBuiltIns: 'usage', corejs: 3,
                    }
                  ],
                  ['@babel/preset-typescript']
                ],
                // npm install -D @babel/plugin-transform-runtime @babel/runtime-corejs3
                plugins: [
                  [
                    // @babel/plugin-transform-runtime 是用来对 Promise, Set, Map 做 polyfill API 补齐的
                    // 补后产物从 4.2k 上升到 55kb
                    '@babel/plugin-transform-runtime',
                    {
                      corejs: 3
                    }
                  ]
                ]
              }
            },
            {
              loader: 'ts-loader',
              options: {
                transpileOnly: true // 只进行转译，不进行类型检查
              }
            }
          ],
          exclude: /node_modules/
        }
      ]
    },
    resolve: {
      extensions: ['.tsx', '.ts', '.js']
    },
    // 把公共依赖抽离给一个叫 vendor.js 的文件
    optimization: {
      splitChunks: {
        name: 'vendor',
        chunks: 'all'
      }
    }
  }
}
